home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / Hydra11s.lha / HBBS / Source / Node / Node_Main.c < prev    next >
C/C++ Source or Header  |  1996-10-31  |  41KB  |  1,342 lines

  1. /*
  2.  
  3.  
  4.    modify NodeGUI.C so that it has these two lines in the OpenNodeWndWindow()
  5.    function.
  6.  
  7.                 (WA_Left), N_ND->NodeX,
  8.                 (WA_Top), N_ND->NodeY,
  9.  
  10.    and so it has these includes and external definition right after "NodeGUI.H"
  11.  
  12.    #include "/common/types.h"
  13.    #include "/common/defines.h"
  14.    #include "/common/structures.h"
  15.  
  16.    extern struct NodeData *N_ND;
  17.  
  18.    todo:
  19.  
  20.    add a CheckNodePaths() sub routine..
  21.  
  22. */
  23.  
  24. #include <stdio.h>
  25. #include <exec/types.h>
  26. #include <libraries/locale.h>
  27. #include <exec/memory.h>
  28. #include <dos/dosextens.h>
  29. #include <intuition/screens.h>
  30. #include <intuition/intuition.h>
  31. #include <intuition/gadgetclass.h>
  32. #include <libraries/gadtools.h>
  33. #include <diskfont/diskfont.h>
  34. #include <utility/utility.h>
  35. #include <graphics/gfxbase.h>
  36. #include <devices/console.h>
  37. #include <devices/serial.h>
  38. #include <devices/timer.h>
  39. #include <workbench/workbench.h>
  40. #include <graphics/scale.h>
  41. #include <clib/locale_protos.h>
  42. #include <clib/exec_protos.h>
  43. #include <clib/wb_protos.h>
  44. #include <clib/intuition_protos.h>
  45. #include <clib/gadtools_protos.h>
  46. #include <clib/graphics_protos.h>
  47. #include <clib/utility_protos.h>
  48. #include <string.h>
  49. #include <clib/diskfont_protos.h>
  50.  
  51. #include <dos/dos.h>
  52. #include <dos/dostags.h>
  53. #include <stdlib.h>
  54. #include <stdio.h>
  55. #include <ctype.h>
  56. #include <time.h>
  57.  
  58. #include <libraries/reqtools.h>
  59.  
  60. #include <clib/alib_protos.h>
  61. #include <clib/dos_protos.h>
  62. #include <clib/reqtools_protos.h>
  63.  
  64. #include "NodeGUI.h"
  65.  
  66. #define MAIN
  67.  
  68. struct ReqToolsBase *ReqToolsBase;
  69.  
  70. #ifdef __SASC
  71. int CXBRK(void) { return(0); }
  72. int _CXBRK(void) { return(0); }
  73. void chkabort(void) {}
  74. #endif
  75.  
  76. #include "/common/types.h"
  77. #include "/common/errors.h"
  78. #include "/common/defines.h"
  79. #include "/common/structures.h"
  80. #include "/common/strings.h"
  81. #include "/common/files.h"
  82. #include "/common/options.h"
  83. #include "/common/release.h"
  84.  
  85. #include "Node_Options.h"
  86. #include "Node_Console_Protos.h"
  87. #include "Node_Serial_Protos.h"
  88. #include "Node_Input_Protos.h"
  89. #include "Node_Misc_Protos.h"
  90.  
  91. #include "/library/hbbscommon_protos.h"
  92. #include "/library/hbbscommon_pragmas.h"
  93. #include "nodelibrary/hbbsnode_protos.h"
  94. #include "nodelibrary/hbbsnode_pragmas.h"
  95.  
  96. long __stack=35000; // *C* how do we change this when the program is running ???
  97.  
  98. char *versionstr="$VER: Node "RELEASE_STR;
  99.  
  100.  
  101. struct Library *HBBSCommonBase=NULL;
  102. struct Library *HBBSNodeBase=NULL;
  103.  
  104. /*** global vars ***/
  105.  
  106. int gargc;
  107. char **gargv;
  108.  
  109.  
  110. // ** ALWAYS define pointers as NULL **
  111.  
  112. struct MsgPort *N_ReplyPort=NULL; // only used in GetBBSGobal so far so might define locally in that..
  113.  
  114. int N_NodeNum=-1;
  115.  
  116. char WindowTitle[50];
  117. char InfoTitle[25];
  118. char SettingsTitle[25];
  119.  
  120. char WatchUserString[80];
  121.  
  122. struct BBSGlobalData *BBSGlobal=NULL;
  123. struct NodeData *N_ND=NULL;
  124. // *C* put in NodeData ?
  125. struct Screen *scr;
  126. struct TextFont *HBBSFont;
  127. UWORD offx;
  128. UWORD offy;
  129. ULONG InfoWinActive=0; // callers, uploads, downloads
  130.  
  131. struct List *HistoryList;  // for Get_Line()
  132. ULONG HistoryItems=0;
  133.  
  134. ULONG rttags[] =
  135. {
  136.   RTGS_Flags, GSREQF_CENTERTEXT,
  137.   RT_Underscore, '_',
  138.   RTEZ_ReqTitle, (ULONG)"Node Message",
  139.   RT_PubScrName, NULL,  // set in main() to BBSGlobal->ScreenInfo.PubScreenName
  140.   TAG_END
  141. };
  142.  
  143. extern struct ColorSpec ScreenColors[];
  144.  
  145. #include "/common/shared.c"
  146.  
  147. void WatchScreenToFront( void )
  148. {
  149.   if (!N_ND->ConOK)
  150.   {
  151.     OpenNodeConsoleWin();
  152.   }
  153.   if (N_ND->ConOK)
  154.   {
  155.     if (N_ND->NodeSettings.UseOwnScreen)
  156.     {
  157.       ScreenToFront(N_ND->ConScr);
  158.     }
  159.     else
  160.     {
  161.       WindowToFront(N_ND->ConWin);
  162.     }
  163.   }
  164. }
  165.  
  166. BOOL PickConScreen( void )
  167. {
  168.   BOOL retval=FALSE;
  169.   struct rtScreenModeRequester *scrmodereq;
  170.  
  171.   if (scrmodereq = rtAllocRequestA (RT_SCREENMODEREQ, NULL))
  172.   {
  173.     if (rtScreenModeRequest (scrmodereq, "Select Screen mode:",RTSC_Flags,SCREQF_GUIMODES | SCREQF_DEPTHGAD | SCREQF_SIZEGADS,
  174.                                                                RT_Window,NodeWnd,
  175.                                                                RTSC_MinHeight,200,
  176.                                                                RTSC_MinWidth,640,
  177.                                                                RTSC_MinDepth,1,
  178.                                                                RTSC_MaxDepth,3,
  179.                                                                TAG_END))
  180.     {
  181.       N_ND->NodeSettings.ScrModeID=scrmodereq->DisplayID;
  182.       N_ND->NodeSettings.ScrHeight=scrmodereq->DisplayHeight;
  183.       N_ND->NodeSettings.ScrWidth=scrmodereq->DisplayWidth;
  184.       N_ND->NodeSettings.ScrDepth=scrmodereq->DisplayDepth;
  185.       retval=TRUE;
  186.     }
  187.     rtFreeRequest(scrmodereq);
  188.   }
  189.   return(retval);
  190. }
  191.  
  192. BOOL CreateNodePorts( void )
  193. {
  194.   N_ND->ReplyPort=NULL; // set to null for FreeNodeData()...
  195.   N_ND->NodePort=NULL;
  196.   if (N_ND->OLMPort=CreateMsgPort())
  197.   {
  198.     if (N_ND->NodePort=CreatePort(N_ND->PortName,0))
  199.     {
  200.       if (N_ND->ReplyPort=CreatePort(0,0)) // don't need to be named..
  201.       {
  202.         return(TRUE);
  203.       }
  204.       else
  205.       {
  206.         DeletePort(N_ND->NodePort);
  207.         N_ND->NodePort=NULL; // set to null for FreeNodeData()...
  208.       }
  209.     }
  210.   }
  211.   return(FALSE);
  212. }
  213.  
  214. void CloseNodePorts( void )
  215. {
  216.   if (N_ND->OLMPort)
  217.   {
  218.     DeletePort(N_ND->OLMPort);
  219.     N_ND->OLMPort=NULL; // do we need ?
  220.   }
  221.   if (N_ND->NodePort)
  222.   {
  223.     DeletePort(N_ND->NodePort);
  224.     N_ND->NodePort=NULL; // do we need ?
  225.   }
  226.   if (N_ND->ReplyPort)
  227.   {
  228.     DeletePort(N_ND->ReplyPort);
  229.     N_ND->ReplyPort=NULL;
  230.   }
  231. }
  232.  
  233. void UpdateNodeWndGadgets( void )
  234. {
  235.   // must update stuff like the chat flag, user on-line, reserved etc.. etc..
  236.   GT_SetGadgetAttrs(NodeWndGadgets[NodeWnd_ChatFlag],NodeWnd,NULL,GTCY_Active,N_ND->NodeSettings.ChatFlag ? 0 : 1,TAG_DONE);
  237. }
  238.  
  239. void OpenNodeWin( struct Screen *scr )
  240. {
  241.   N_ND->NodeSettings.Iconified=TRUE; // just in case the window does not open..
  242.   if (OpenNodeWndWindow(scr)==0)
  243.   {
  244.     N_ND->NodeWnd=NodeWnd; // update node structure
  245.     offx = NodeWnd->BorderLeft;
  246.     offy = NodeWnd->BorderTop;
  247.     sprintf(WindowTitle,"HBBS Node %d Control Window! (C) Hydra/LSD",N_NodeNum);
  248.     SetWindowTitles(NodeWnd,WindowTitle,(UBYTE *) ~0);
  249.     UpdateNodeWndGadgets();
  250.     N_ND->NodeSettings.Iconified=FALSE;
  251.     DOOR_UpdateNodeStatus(UPD_NAME);
  252.     DOOR_UpdateNodeStatus(UPD_GROUP);
  253.     DOOR_UpdateNodeStatus(UPD_ACTION);
  254.     DOOR_UpdateNodeStatus(UPD_CPSBAUD);
  255.   }
  256. }
  257.  
  258. void CloseNodeWin(void)
  259. {
  260.   N_ND->NodeX=NodeWnd->LeftEdge;
  261.   N_ND->NodeY=NodeWnd->TopEdge;
  262.  
  263.   CloseNodeWndWindow();
  264.   N_ND->NodeSettings.Iconified=TRUE;
  265.   N_ND->NodeWnd=NULL; // update node structure
  266. }
  267.  
  268. /*** GUI ***/
  269.  
  270. void UpdateInfoWin( void )
  271. {
  272.   if (N_ND->InformationOpen)
  273.   {
  274.     sprintf(InfoTitle,"Info For Node %d",N_NodeNum);
  275.     SetWindowTitles(InfoWin,InfoTitle,(UBYTE *)~0);
  276.  
  277.     // update the list view..
  278.     // depending on what the user's looking at...
  279.  
  280.     switch(InfoWinActive)
  281.     {
  282.       case 0:
  283.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Callers,GTLV_Top,0,TAG_DONE);
  284.         break;
  285.       case 1:
  286.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Uploads,GTLV_Top,0,TAG_DONE);
  287.         break;
  288.       case 2:
  289.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Downloads,GTLV_Top,0,TAG_DONE);
  290.         break;
  291.       case 3:
  292.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Pagers,GTLV_Top,0,TAG_DONE);
  293.         break;
  294.       case 4:
  295.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_PWFails,GTLV_Top,0,TAG_DONE);
  296.         break;
  297.       case 5:
  298.         GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_LV1],InfoWin,NULL,GTLV_Labels,N_ND->Last_Carrier,GTLV_Top,0,TAG_DONE);
  299.         break;
  300.     }
  301.  
  302.     // update the calls number..
  303.     GT_SetGadgetAttrs(InfoWinGadgets[InfoWin_Calls],InfoWin,NULL,GTNM_Number,N_ND->CallsToday,TAG_DONE);
  304.  
  305.  
  306.   }
  307. }
  308.  
  309. void ProcessWindowInfoWin( LONG Class, UWORD Code, APTR IAddress )
  310. {
  311. struct Gadget *gad;
  312. switch ( Class )
  313.   {
  314.   case IDCMP_GADGETUP :
  315.     /* Gadget message, gadget = gad. */
  316.     gad = (struct Gadget *)IAddress;
  317.     switch ( gad->GadgetID )
  318.       {
  319.       case InfoWin_LV1_Cycle1 :
  320.         /* Cycle changed   , Text of gadget :  */
  321.         InfoWinActive=Code;
  322.         UpdateInfoWin();
  323.         break;
  324.       case InfoWin_LV1 :
  325.         /* ListView pressed, Text of gadget :  */
  326.         break;
  327.       }
  328.     break;
  329.   case IDCMP_CLOSEWINDOW :
  330.     /* CloseWindow Now */
  331.     CloseInfoWinWindow();
  332.     N_ND->InformationOpen=FALSE;
  333.     break;
  334.   case IDCMP_REFRESHWINDOW :
  335.     GT_BeginRefresh( InfoWin);
  336.     /* Refresh window. */
  337.     RendWindowInfoWin( InfoWin, InfoWinVisualInfo );
  338.     GT_EndRefresh( InfoWin, TRUE);
  339.     GT_RefreshWindow( InfoWin, NULL);
  340.     RefreshGList( InfoWinGList, InfoWin, NULL, ~0);
  341.     DOOR_UpdateNodeStatus(UPD_NAME);
  342.     DOOR_UpdateNodeStatus(UPD_GROUP);
  343.     DOOR_UpdateNodeStatus(UPD_ACTION);
  344.     DOOR_UpdateNodeStatus(UPD_CPSBAUD);
  345.     break;
  346.   }
  347. }
  348.  
  349. void UpdateSettingsWindow( void )
  350. {
  351.   if (N_ND->SettingsOpen)
  352.   {
  353.     sprintf(SettingsTitle,"Settings For Node %d",N_NodeNum);
  354.     SetWindowTitles(SettingsWin,SettingsTitle,(UBYTE *)~0);
  355.  
  356.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_ModemDebug],SettingsWin,NULL,GTCB_Checked,N_ND->NodeDevice.ModemDebug,TAG_DONE);
  357.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_ModemLog],SettingsWin,NULL,GTCB_Checked,N_ND->NodeDevice.ModemLog,TAG_DONE);
  358.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_WinOrScreen],SettingsWin,NULL,GTCY_Active,N_ND->NodeSettings.UseOwnScreen ? 0 : 1,TAG_DONE);
  359.     GT_SetGadgetAttrs(SettingsWinGadgets[SettingsWin_AllowLogins],SettingsWin,NULL,GTCY_Active,N_ND->AllowLogins ? 0 : 1,TAG_DONE);
  360.   }
  361. }
  362.  
  363. void LoadWindowSettings( void )
  364. {
  365.   struct CfgFileData *WindowCFG;
  366.   char tmpstr[BIG_STR],optionstr[10],*paramstr;
  367.   ULONG loop;
  368.   ULONG col1,col2,col3;
  369.   N_ND->ConX=0;
  370.   N_ND->ConY=11;
  371.   N_ND->ConW=640;
  372.   N_ND->ConH=200-11;
  373.  
  374.  
  375.   sprintf(tmpstr,"%sScreen.CFG",N_ND->NodeLocation);
  376.  
  377.   if (WindowCFG=HBBS_LoadConfig(tmpstr,LCFG_NONE))
  378.   {
  379.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeX,VTYPE_BIGNUM,"NodeWnd_LeftEdge",OPT_SINGLE);
  380.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeY,VTYPE_BIGNUM,"NodeWnd_TopEdge",OPT_SINGLE);
  381.  
  382.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConX,VTYPE_BIGNUM,"ConWin_LeftEdge",OPT_SINGLE);
  383.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConY,VTYPE_BIGNUM,"ConWin_TopEdge",OPT_SINGLE);
  384.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConW,VTYPE_BIGNUM,"ConWin_Width",OPT_SINGLE);
  385.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->ConH,VTYPE_BIGNUM,"ConWin_Height",OPT_SINGLE);
  386.  
  387.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrModeID,VTYPE_BIGNUM,OPT_NODE_ScrModeID,OPT_SINGLE);
  388.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrHeight,VTYPE_BIGNUM,OPT_NODE_ScrHeight,OPT_SINGLE);
  389.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrWidth,VTYPE_BIGNUM,OPT_NODE_ScrWidth,OPT_SINGLE);
  390.     HBBS_GetSetting(WindowCFG,(void *)&N_ND->NodeSettings.ScrDepth,VTYPE_BIGNUM,OPT_NODE_ScrDepth,OPT_SINGLE);
  391.  
  392.     for (loop=0;loop<8;loop++)
  393.     {
  394.       sprintf(optionstr,"Colour_%d",loop);
  395.       paramstr=NULL;
  396.       if (HBBS_GetSetting(WindowCFG,(void *)¶mstr,VTYPE_STRING,optionstr,OPT_SINGLE))
  397.       {
  398.         if (sscanf(paramstr,"%ld %ld %ld",&col1,&col2,&col3)==3)
  399.         {
  400.           ScreenColors[loop].Red=(UWORD)col1;
  401.           ScreenColors[loop].Green=(UWORD)col2;
  402.           ScreenColors[loop].Blue=(UWORD)col3;
  403.         }
  404.         FreeStr(paramstr);
  405.       }
  406.     }
  407.  
  408.     HBBS_FlushConfig(WindowCFG);
  409.   }
  410.  
  411. }
  412.  
  413. void SaveWindowSettings( void )
  414. {
  415.   struct CfgFileData *WindowCFG;
  416.   char filename[BIG_STR],tmpstr[BIG_STR],optionstr[BIG_STR];
  417.   ULONG loop;
  418.  
  419.   sprintf(filename,"%sScreen.CFG",N_ND->NodeLocation);
  420. //  sprintf(filename,"HBBS:System/Data/Node%d_Private.CFG",N_NodeNum);
  421.  
  422.   if (WindowCFG=HBBS_CreateConfig(filename))
  423.   {
  424.     sprintf(tmpstr,"%d",NodeWnd->LeftEdge);
  425.     HBBS_AddCfgItemQuick(WindowCFG,"NodeWnd_LeftEdge",tmpstr);   // *C* make strings into variables!
  426.     sprintf(tmpstr,"%d",NodeWnd->TopEdge);
  427.     HBBS_AddCfgItemQuick(WindowCFG,"NodeWnd_TopEdge",tmpstr);
  428.  
  429.     sprintf(tmpstr,"%d",N_ND->ConWin->LeftEdge);
  430.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_LeftEdge",tmpstr);
  431.     sprintf(tmpstr,"%d",N_ND->ConWin->TopEdge);
  432.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_TopEdge",tmpstr);
  433.     sprintf(tmpstr,"%d",N_ND->ConWin->Width);
  434.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_Width",tmpstr);
  435.     sprintf(tmpstr,"%d",N_ND->ConWin->Height);
  436.     HBBS_AddCfgItemQuick(WindowCFG,"ConWin_Height",tmpstr);
  437.  
  438.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrModeID);
  439.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrModeID,tmpstr);
  440.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrHeight);
  441.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrHeight,tmpstr);
  442.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrWidth);
  443.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrWidth,tmpstr);
  444.     sprintf(tmpstr,"%d",N_ND->NodeSettings.ScrDepth);
  445.     HBBS_AddCfgItemQuick(WindowCFG,OPT_NODE_ScrDepth,tmpstr);
  446.  
  447.     for (loop=0;loop<8;loop++)
  448.     {
  449.       sprintf(tmpstr,"%ld %ld %ld",ScreenColors[loop].Red,ScreenColors[loop].Green,ScreenColors[loop].Blue);
  450.       sprintf(optionstr,"Colour_%d",loop);
  451.       HBBS_AddCfgItemQuick(WindowCFG,optionstr,tmpstr);
  452.     }
  453.  
  454.     if (!HBBS_SaveConfig(WindowCFG))
  455.     {
  456.       HBBS_DoErrorMessage(EMSG_CANTSAVEFILE,N_NodeNum,filename);
  457.     }
  458.     HBBS_FlushConfig(WindowCFG);
  459.   }
  460. }
  461.  
  462. void ProcessWindowSettingsWin( LONG Class, UWORD Code, APTR IAddress )
  463. {
  464. char tmpstr[1024],filename[1024];
  465. struct Gadget *gad;
  466. switch ( Class )
  467.   {
  468.   case IDCMP_GADGETUP :
  469.     /* Gadget message, gadget = gad. */
  470.     gad = (struct Gadget *)IAddress;
  471.     switch ( gad->GadgetID )
  472.       {
  473.       case SettingsWin_ScreenMode :
  474.         if (PickConScreen())
  475.         {
  476.           if (N_ND->NodeSettings.UseOwnScreen)
  477.           {
  478.             if (N_ND->ConOK) CleanupNodeConsoleWin();
  479.             OpenNodeConsoleWin();
  480.           }
  481.         }
  482.         break;
  483. /*
  484.       case SettingsWin_Save :
  485.         break;
  486. */
  487.       case SettingsWin_SaveWin:
  488.         SaveWindowSettings();
  489.         break;
  490.       case SettingsWin_WinOrScreen :
  491.         ChangeConsoleMode(Code); // 0 for screen or 1 for window,2 for reverse
  492.         break;
  493.       case SettingsWin_ModemDebug :
  494.         N_ND->NodeDevice.ModemDebug=!N_ND->NodeDevice.ModemDebug;
  495.         break;
  496.       case SettingsWin_ModemLog :
  497.         N_ND->NodeDevice.ModemLog=!N_ND->NodeDevice.ModemLog;
  498.         break;
  499.       case SettingsWin_AllowLogins :
  500.         N_ND->AllowLogins=!N_ND->AllowLogins;
  501.         break;
  502.       case SettingsWin_NodeConfig :
  503.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  504.         sprintf(filename,"%sNodeLocal",N_ND->NodeLocation);
  505.         replace(tmpstr,tmpstr,"{FILE}",filename);
  506.         HBBS_RunDOSCMD(tmpstr,TRUE);
  507.         break;
  508.       case SettingsWin_CallersLog:
  509.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  510.         replace(tmpstr,tmpstr,"{FILE}",N_ND->NodeSettings.CallersLogFile);
  511.         HBBS_RunDOSCMD(tmpstr,TRUE);
  512.         break;
  513.       case SettingsWin_DeviceConfig :
  514.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  515.         sprintf(filename,"%sDevice",N_ND->NodeLocation);
  516.         replace(tmpstr,tmpstr,"{FILE}",filename);
  517.         HBBS_RunDOSCMD(tmpstr,TRUE);
  518.         break;
  519.       }
  520.     break;
  521.   case IDCMP_CLOSEWINDOW :
  522.     CloseSettingsWinWindow();
  523.     N_ND->SettingsOpen=FALSE;
  524.     // updatesettings();
  525.     break;
  526.   case IDCMP_REFRESHWINDOW :
  527.     GT_BeginRefresh( SettingsWin);
  528.     /* Refresh window. */
  529.   RendWindowSettingsWin( SettingsWin, SettingsWinVisualInfo );
  530.     GT_EndRefresh( SettingsWin, TRUE);
  531.   GT_RefreshWindow( SettingsWin, NULL);
  532.   RefreshGList( SettingsWinGList, SettingsWin, NULL, ~0);
  533.     break;
  534.   }
  535. }
  536.  
  537. void ProcessWindowNodeWnd( LONG Class, UWORD Code, APTR IAddress )
  538. {
  539. struct Gadget *gad;
  540. switch ( Class )
  541.   {
  542.   case IDCMP_GADGETUP :
  543.     /* Gadget message, gadget = gad. */
  544.     gad = (struct Gadget *)IAddress;
  545.     switch ( gad->GadgetID )
  546.       {
  547.       case NodeWnd_ChatFlag :
  548.         N_ND->NodeSettings.ChatFlag= Code == 0 ? TRUE : FALSE;
  549.         break;
  550.       case NodeWnd_OffHook :
  551.         /* Button pressed  , Text of gadget : OffHook */
  552.  
  553.         if (N_ND->OnlineStatus==OS_OFFLINE)
  554.         {
  555.           if (Code==0) // onhook...
  556.           {
  557.             InitModem();
  558.           }
  559.           if (Code==1) // off hook
  560.           {
  561.             OffHook();
  562.           }
  563.         }
  564.         else
  565.         {
  566.           if (Code==0) Code = 1; else Code=0;
  567.           // put the gadget back to what it was!
  568.           GT_SetGadgetAttrs(NodeWndGadgets[NodeWnd_OffHook],NodeWnd,NULL,GTCY_Active,Code,TAG_DONE);
  569.         }
  570.         break;
  571.       case NodeWnd_InitModem :
  572.         /* Button pressed  , Text of gadget : Init Modem */
  573.  
  574.         // only do it if no one's online..
  575.  
  576.         if (N_ND->OnlineStatus==OS_OFFLINE) InitModem();
  577.         break;
  578.       case NodeWnd_Reserve :
  579.         break;
  580.       case NodeWnd_Screen :
  581.         if (N_ND->ConOK)
  582.         {
  583.           CleanupNodeConsoleWin();
  584.         }
  585.         else
  586.         {
  587.           WatchScreenToFront();
  588.         }
  589.         break;
  590.       case NodeWnd_ChatNow :
  591.         /* Button pressed  , Text of gadget : Chat Now */
  592.  
  593.         if (N_ND->OnlineStatus==OS_ONLINE)
  594.         {
  595.           // open watch window if closed and/or bring it to the front.
  596.  
  597.           WatchScreenToFront();
  598.  
  599.           if (N_ND->ConOK) // check again as if we had to open the watch window it might not have actually opened...
  600.           {
  601.             if ((N_ND->ActiveDoor==NULL) || (N_ND->ActiveDoor) && (iposition("SYSOPCHAT",N_ND->ActiveDoor->node.ln_Name)<0))
  602.             {
  603.               // only start the door if it's not already started..
  604.  
  605.               GoSystemDoor("SYSOPCHAT",NULL);
  606.             }
  607.           }
  608.         }
  609.         else DisplayBeep(scr); // Doh! Can't chat to user if no-one's logged on m8! :-)
  610.  
  611.         break;
  612.       case NodeWnd_Settings :
  613.         /* Button pressed  , Text of gadget : Settings */
  614.         if (N_ND->SettingsOpen==FALSE)
  615.         {
  616.           if (OpenSettingsWinWindow(scr)==0) // success!
  617.           {
  618.             N_ND->SettingsOpen=TRUE;
  619.             UpdateSettingsWindow();
  620.           }
  621.         }
  622.         else
  623.         {
  624.           WindowToFront(SettingsWin);
  625.         }
  626.         break;
  627.       case NodeWnd_Information :
  628.         /* Button pressed  , Text of gadget : Information */
  629.         if (N_ND->InformationOpen==FALSE)
  630.         {
  631.           if (OpenInfoWinWindow(scr)==0) // success!
  632.           {
  633.             N_ND->InformationOpen=TRUE;
  634.             UpdateInfoWin();
  635.           }
  636.         }
  637.         break;
  638.       }
  639.     break;
  640.   case IDCMP_CLOSEWINDOW :
  641.     /* CloseWindow Now */
  642.     if (N_ND->NodeSettings.Iconified==FALSE)
  643.     {
  644.       CloseNodeWin();
  645. // *R* moved to clodenodewin();
  646. //      N_ND->NodeX=N_ND->NodeWnd->LeftEdge;
  647. //      N_ND->NodeY=N_ND->NodeWnd->TopEdge;
  648.     }
  649.     break;
  650.   case IDCMP_REFRESHWINDOW :
  651.     GT_BeginRefresh( NodeWnd);
  652.     /* Refresh window. */
  653.   RendWindowNodeWnd( NodeWnd, NodeWndVisualInfo );
  654.     GT_EndRefresh( NodeWnd, TRUE);
  655.   GT_RefreshWindow( NodeWnd, NULL);
  656.   RefreshGList( NodeWndGList, NodeWnd, NULL, ~0);
  657.     break;
  658.   case IDCMP_VANILLAKEY :
  659.     /* Processed key press */
  660.     /* gadgets need processing perhaps. */
  661.     break;
  662.   }
  663. }
  664.  
  665. void ProcessConWindow( LONG Class, UWORD Code, APTR IAddress )
  666. {
  667. //  struct Gadget *gad;
  668.  
  669.   switch ( Class )
  670.   {
  671.     case IDCMP_CLOSEWINDOW :
  672.       /* CloseWindow Now */
  673.  
  674.       // get thesetings for the window position now so that it will open in the same place
  675.       CleanupNodeConsoleWin();
  676.       break;
  677.     case IDCMP_REFRESHWINDOW :
  678.       GT_BeginRefresh( NodeWnd);
  679.       /* Refresh window. */
  680.       RendWindowNodeWnd( NodeWnd, NodeWndVisualInfo );
  681.       GT_EndRefresh( NodeWnd, TRUE);
  682.       GT_RefreshWindow( NodeWnd, NULL);
  683.       RefreshGList( NodeWndGList, NodeWnd, NULL, ~0);
  684.       break;
  685.   }
  686. }
  687.  
  688. void SendStatus(V_BIGNUM status)
  689. {
  690.   struct StatusMsg *SMsg;
  691.  
  692.   if (SMsg=(struct StatusMsg *)AllocVec(sizeof(struct StatusMsg),MEMF_PUBLIC))
  693.   {
  694.     SMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  695.     SMsg->message.mn_ReplyPort=NULL;//N_ND->ReplyPort;
  696.     SMsg->message.mn_Length=sizeof(struct StatusMsg);
  697.     SMsg->MsgType=mtype_STATUS;
  698.     SMsg->NodeNum=N_ND->NodeNum;
  699.     SMsg->Status=status;
  700.     SendMessage((struct Message*)SMsg,CtrlMainPortName);
  701.   }
  702. }
  703.  
  704. void SendRequest(V_BIGNUM requesttype)
  705. {
  706.   struct RequestMsg *RMsg;
  707.  
  708.   if (RMsg=(struct RequestMsg *)AllocVec(sizeof(struct RequestMsg),MEMF_PUBLIC))
  709.   {
  710.     RMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  711.     RMsg->message.mn_ReplyPort=NULL;//N_ND->ReplyPort;
  712.     RMsg->message.mn_Length=sizeof(struct RequestMsg);
  713.     RMsg->MsgType=mtype_REQUEST;
  714.     RMsg->NodeNum=N_ND->NodeNum;
  715.     RMsg->Flags=requesttype;
  716.     SendMessage((struct Message*)RMsg,CtrlMainPortName);
  717.   }
  718. }
  719.  
  720.  
  721. void ClearDeviceData(struct DeviceData *DD)
  722. {
  723.   // small subroutine to set all the default values
  724.   // never call if you've allocated mem for strings!
  725.   DD->DeviceName=NULL;
  726.   DD->SerialDevice=NULL;
  727.   DD->SerialUnit=0;
  728.   DD->SerialBaud=0;
  729.   DD->NullModemCable=FALSE;
  730.   DD->ModemDebug=FALSE;
  731.   DD->ModemLog=FALSE;
  732.   DD->EchoRetries=0;
  733.   DD->ReOpenRetries=0;
  734.   DD->ReOpenDelay=0;
  735.   DD->LockUpScript=NULL;
  736.   DD->MaxCommandWait=0;
  737.   DD->CommandRetries=0;
  738.   DD->DelayBetweenCmds=0;
  739.   DD->TildeDelay=0;
  740.   DD->TurnOnEcho=NULL;
  741.   DD->TurnOnEchoDelay=0;
  742.   DD->ModemInit=NULL;
  743.   DD->StrictConnect=FALSE;
  744.   DD->StrictConnectStr=NULL;
  745.   DD->RelaxedConnectStr=NULL;
  746.   DD->CommandModeString=NULL;
  747.   DD->DropDTRHangup=FALSE;
  748.   DD->HangUpString=NULL;
  749.   DD->OffHookString=NULL;
  750.   DD->Incoming=NULL;
  751.   DD->ImmediateAnswer=NULL;
  752. }
  753.  
  754. void SetDeviceDataDefaults(struct DeviceData *DD)
  755. {
  756.   // small subroutine to set all the default values
  757.  
  758.   DD->EchoRetries=4;
  759.   DD->ReOpenRetries=2;
  760.   DD->ReOpenDelay=25;
  761.   DD->MaxCommandWait=10;
  762.   DD->CommandRetries=3;
  763.   DD->DelayBetweenCmds=1;
  764.   DD->TildeDelay=22;
  765.   DD->TurnOnEchoDelay=20;
  766.   DD->DropDTRHangup=TRUE;
  767. }
  768.  
  769. void FreeDeviceData(struct DeviceData *DD)
  770. {
  771.   FreeStr(DD->DeviceName);
  772.   FreeStr(DD->SerialDevice);
  773.   FreeStr(DD->LockUpScript);
  774.   FreeStr(DD->HangUpString);
  775.   FreeStr(DD->OffHookString);
  776.   FreeStr(DD->Incoming);
  777.   FreeStr(DD->ImmediateAnswer);
  778.   FreeStrList(DD->TurnOnEcho);
  779.   FreeStrList(DD->ModemInit);
  780.   FreeStrList(DD->StrictConnectStr);
  781.   FreeStrList(DD->CommandModeString);
  782.   FreeStrList(DD->RelaxedConnectStr);
  783. }
  784.  
  785. V_ERROR LoadDeviceData(ULONG NodeNum,struct DeviceData *DD )
  786. {
  787.   struct CfgFileData *DeviceCFG;
  788.   V_ERROR error=TYPE_NONE;
  789.   UBYTE ecode=0;
  790.   UBYTE *filename=NULL;
  791.   struct NodeData *ND;
  792.  
  793.   if (ND=HBBS_NodeDataPtr(NodeNum))
  794.   {
  795.     if (filename=AllocVec(strlen(ND->NodeLocation)+strlen(FILENAME_DEVICE)+1,MEMF_PUBLIC))
  796.     {
  797.       strcpy(filename,ND->NodeLocation);
  798.       strcat(filename,FILENAME_DEVICE);
  799.     }
  800.   }
  801.  
  802.   if (filename)
  803.   {
  804.     if (DeviceCFG=HBBS_LoadConfig(filename,LCFG_NONE))
  805.     {
  806.       // get settings!
  807.  
  808.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->DeviceName       ,VTYPE_STRING,OPT_DEVICE_DeviceName       ,OPT_SINGLE)) ecode=1;
  809.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->SerialDevice     ,VTYPE_STRING,OPT_DEVICE_SerialDevice     ,OPT_SINGLE)) ecode=2;
  810.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->SerialUnit       ,VTYPE_BIGNUM,OPT_DEVICE_SerialUnit       ,OPT_SINGLE)) ecode=3;
  811.       if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->SerialBaud       ,VTYPE_BIGNUM,OPT_DEVICE_SerialBaud       ,OPT_SINGLE)) ecode=4;
  812.       /*if (!*/HBBS_GetSetting(DeviceCFG,(void *)&DD->NullModemCable   ,VTYPE_BOOL,OPT_DEVICE_NullModemCable     ,OPT_SINGLE);/*) ecode=5;*/
  813.       if (!DD->NullModemCable)
  814.       {
  815.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ModemDebug       ,VTYPE_BOOL,OPT_DEVICE_ModemDebug         ,OPT_SINGLE)) ecode=6;
  816.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ModemLog         ,VTYPE_BOOL,OPT_DEVICE_ModemLog           ,OPT_SINGLE)) ecode=7;
  817.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->EchoRetries      ,VTYPE_SMALLNUM,OPT_DEVICE_EchoRetries    ,OPT_SINGLE)) ecode=8;
  818.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ReOpenRetries    ,VTYPE_SMALLNUM,OPT_DEVICE_ReOpenRetries  ,OPT_SINGLE)) ecode=9;
  819.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ReOpenDelay      ,VTYPE_TIME,OPT_DEVICE_ReOpenDelay        ,OPT_SINGLE)) ecode=10;
  820.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->LockUpScript     ,VTYPE_STRING,OPT_DEVICE_LockUpScript     ,OPT_SINGLE)) ecode=11;
  821.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->MaxCommandWait   ,VTYPE_TIME,OPT_DEVICE_MaxCommandWait     ,OPT_SINGLE)) ecode=12;
  822.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->CommandRetries   ,VTYPE_SMALLNUM,OPT_DEVICE_CommandRetries ,OPT_SINGLE)) ecode=13;
  823.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->DelayBetweenCmds ,VTYPE_TIME,OPT_DEVICE_DelayBetweenCmds   ,OPT_SINGLE)) ecode=14;
  824.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->TildeDelay       ,VTYPE_TIME,OPT_DEVICE_TildeDelay         ,OPT_SINGLE)) ecode=15;
  825.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->TurnOnEcho       ,VTYPE_STRINGLIST,OPT_DEVICE_TurnOnEcho   ,OPT_MULTI)) ecode=16;
  826.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->TurnOnEchoDelay  ,VTYPE_BIGNUM,OPT_DEVICE_TurnOnEchoDelay  ,OPT_SINGLE)) ecode=17;
  827.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ModemInit        ,VTYPE_STRINGLIST,OPT_DEVICE_ModemInit    ,OPT_MULTI)) ecode=18;
  828.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->StrictConnect    ,VTYPE_BOOL,OPT_DEVICE_StrictConnect      ,OPT_SINGLE)) ecode=19;
  829.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->StrictConnectStr ,VTYPE_STRINGLIST,OPT_DEVICE_StrictConnectStr ,OPT_MULTI) && DD->StrictConnect) ecode=20;
  830.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->RelaxedConnectStr,VTYPE_STRINGLIST,OPT_DEVICE_RelaxedConnectStr,OPT_MULTI) && !DD->StrictConnect) ecode=21;
  831.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->DropDTRHangup    ,VTYPE_BOOL,OPT_DEVICE_DropDTRHangup      ,OPT_SINGLE)) ecode=22;
  832.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->CommandModeString,VTYPE_STRINGLIST,OPT_DEVICE_CommandModeString,OPT_MULTI)) ecode=23;
  833.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->HangUpString     ,VTYPE_STRING,OPT_DEVICE_HangUpString     ,OPT_SINGLE)) ecode=24;
  834.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->OffHookString    ,VTYPE_STRING,OPT_DEVICE_OffHookString    ,OPT_SINGLE)) ecode=25;
  835.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->Incoming         ,VTYPE_STRING,OPT_DEVICE_Incoming         ,OPT_SINGLE)) ecode=26;
  836.         if (!HBBS_GetSetting(DeviceCFG,(void *)&DD->ImmediateAnswer  ,VTYPE_STRING,OPT_DEVICE_ImmediateAnswer  ,OPT_SINGLE)) ecode=27;
  837.       }
  838.  
  839.       if (ecode>0)
  840.       {
  841.         error=TYPE_FATAL;
  842.         HBBS_DoErrorMessage(EMSG_DEVICECFG+ecode-1,N_NodeNum,filename);
  843.       }
  844.       HBBS_FlushConfig(DeviceCFG);
  845.       DD->SysopNode=FALSE;
  846.     }
  847.     else
  848.     {
  849.       DD->SysopNode=TRUE;
  850.     }
  851.     FreeVec(filename);
  852.   }
  853.   return(error);
  854. }
  855.  
  856.  
  857. static VOID cleanup(ULONG num)
  858. {
  859.   if (HBBSNodeBase)
  860.   {
  861.     HBBS_CleanUpNode();
  862.     CloseLibrary (HBBSNodeBase);
  863.   }
  864.  
  865.   if (HBBSCommonBase)
  866.   {
  867.     HBBS_CleanUpCommon();
  868.     CloseLibrary (HBBSCommonBase);
  869.   }
  870.  
  871.   if (N_ReplyPort)
  872.     DeleteMsgPort(N_ReplyPort);
  873.  
  874.   if (num)
  875.   {
  876.     HBBS_DoErrorMessage(num,N_NodeNum,NULL);
  877.   }
  878.  
  879.   if (ReqToolsBase)
  880.     CloseLibrary ((struct Library *)ReqToolsBase);
  881.  
  882.   exit(0);
  883. }
  884.  
  885. static VOID init(VOID)
  886. {
  887.   if (!(ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
  888.   {
  889.     cleanup(EMSG_NOREQTOOLS);
  890.   }
  891.  
  892.   if (!(N_ReplyPort=CreateMsgPort()))
  893.   {
  894.     cleanup(EMSG_NOMEM);
  895.   }
  896.  
  897.   if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  898.   {
  899.     cleanup(EMSG_NOCOMMON);
  900.   }
  901.  
  902.   if (!(HBBS_InitCommon()))
  903.   {
  904.     cleanup(EMSG_COMMONERR);
  905.   }
  906.  
  907.   if(!(HBBSNodeBase = OpenLibrary("HBBSNode.library",0)))
  908.   {
  909.     cleanup(EMSG_NONODE);
  910.   }
  911.  
  912.   if (!(HBBS_InitNode(N_NodeNum)))
  913.   {
  914.     cleanup(EMSG_NODEERR);
  915.   }
  916. }
  917.  
  918. /*
  919. V_ERROR GetBBSGlobal(void)
  920. {
  921.   struct AskMsg *AMsg,*Reply;
  922.   V_ERROR error=TYPE_CRITICAL;
  923.  
  924.   if (AMsg=(struct AskMsg *)AllocVec(sizeof(struct AskMsg),MEMF_PUBLIC))
  925.   {
  926.     // create the message
  927.     AMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  928.     AMsg->message.mn_ReplyPort=N_ReplyPort;
  929.     AMsg->message.mn_Length=sizeof(struct AskMsg);
  930.     AMsg->MsgType=mtype_ASK; // so CONTROL knows what type of message structe to typecast to..
  931.     AMsg->NodeNum=N_NodeNum; // can't use N_ND->NodeNum yet.. as we don't know N_ND
  932.     AMsg->Flags=ASK_BBSGLOBAL;
  933.  
  934.     // now send it to ctrlmain, note we can't use N_ND->ReplyPort as we don't know N_ND yet!!
  935.  
  936.     if (SafePutToPort((struct Message *)AMsg,CtrlMainPortName))
  937.     {
  938.       if (1L << N_ReplyPort->mp_SigBit==Wait(1L << N_ReplyPort->mp_SigBit))
  939.       {
  940.         Reply=(struct AskMsg*)GetMsg(N_ReplyPort);
  941.         if (Reply)
  942.         {
  943.           BBSGlobal=(struct BBSGlobalData *)Reply->Pointer;
  944.           error=TYPE_NONE;
  945.         }
  946.       }
  947.     }
  948.     FreeVec(AMsg);
  949.   }
  950.   return(error);
  951. }
  952. */
  953. V_BOOL InitNode(void)
  954. {
  955.   int loop;
  956.   struct Node *node;
  957.   V_BOOL error=FALSE;
  958.   UBYTE ecode=0;
  959.   // *C* add error messages and return codes here ?
  960.   if (!CreateNodePorts())
  961.   {
  962.     ecode=1;
  963.   }
  964.   else
  965.   {
  966.     // ports must be created before sendstatus will work..
  967.     SendStatus(STAT_INITIALIZING);
  968.     ecode=2;
  969.     if (N_ND->BBSCols=(struct BBSColsData*)AllocVec(sizeof(struct BBSColsData),MEMF_CLEAR|MEMF_PUBLIC))
  970.     {
  971.       if (N_ND->OLMList=HBBS_CreateList())
  972.       {
  973.         N_ND->User.ConfAcs.Name=NULL;
  974.         N_ND->OLMCount=0;
  975.         if (N_ND->Last_Callers=HBBS_CreateList())
  976.         {
  977.           if (N_ND->Last_Uploads=HBBS_CreateList())
  978.           {
  979.             if (N_ND->Last_Downloads=HBBS_CreateList())
  980.             {
  981.               if (N_ND->Last_PWFails=HBBS_CreateList())
  982.               {
  983.                 if (N_ND->Last_Carrier=HBBS_CreateList())
  984.                 {
  985.                   if (N_ND->Last_Pagers=HBBS_CreateList())
  986.                   {
  987.                     if (N_ND->User.ConfAcs.See=HBBS_CreateList())
  988.                     {
  989.                       for (loop=0;(!error) && (loop<BBSGlobal->Conferences);loop++)
  990.                       {
  991.                         if (node=AllocVec(sizeof(struct BoolNode),MEMF_CLEAR|MEMF_PUBLIC))
  992.                         {
  993.                           AddTail(N_ND->User.ConfAcs.See,node);
  994.                         }
  995.                         else error=TRUE;
  996.                       }
  997.                       if (!error)
  998.                       {
  999.                         if (N_ND->User.ConfAcs.Access=HBBS_CreateList())
  1000.                         {
  1001.                           for (loop=0;(!error) && (loop<BBSGlobal->Conferences);loop++)
  1002.                           {
  1003.                             if (node=AllocVec(sizeof(struct BoolNode),MEMF_CLEAR|MEMF_PUBLIC))
  1004.                             {
  1005.                               AddTail(N_ND->User.ConfAcs.Access,node);
  1006.                             }
  1007.                             else error=TRUE;
  1008.                           }
  1009.                           if (!error)
  1010.                           {
  1011.                             ecode=0;
  1012.                             ClearNodeData(&N_ND->NodeSettings);
  1013.                             ClearDeviceData(&N_ND->NodeDevice);
  1014.                             SetDeviceDataDefaults(&N_ND->NodeDevice);
  1015.                             CopyNodeSettings(&N_ND->NodeSettings,&BBSGlobal->NodeGlobalData->NodeSettings);
  1016.                             N_ND->NodeFlags=NFLG_NONE;
  1017.                             if (LoadNodeSettingsData(N_NodeNum,&N_ND->NodeSettings)==TYPE_NONE)
  1018.                             {
  1019.                               HBBS_SetBBSCols();
  1020.                               if (N_ND->NodeTimer=InitTimer())
  1021.                               {
  1022.                                 if (N_ND->NodeSettings.UseDevice)
  1023.                                 {
  1024.                                   if (LoadDeviceData(N_NodeNum,&N_ND->NodeDevice)==TYPE_NONE)
  1025.                                   {
  1026.                                     if (OpenSerial())
  1027.                                     {
  1028.                                       return(TRUE);
  1029.                                     }
  1030.                                   } else ecode=3; //HBBS_DoErrorMessage(EMSG_DEVICEFILEERR,N_ND->NodeNum,NULL);
  1031.                                 }
  1032.                                 else
  1033.                                 {
  1034.                                   return(TRUE);
  1035.                                 }
  1036.                               } else ecode=4; //HBBS_DoErrorMessage(EMSG_NOTIMER,N_ND->NodeNum,NULL);
  1037.                             } else HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_NODESETTINGS,NULL,TYPE_FATAL);
  1038.                           }
  1039.                         }
  1040.                       }
  1041.                     }
  1042.                   }
  1043.                 }
  1044.               }
  1045.             }
  1046.           }
  1047.         }
  1048.       }
  1049.     }
  1050.     SendStatus(STAT_CLOSED);
  1051.   }
  1052.   if (ecode) HBBS_DoErrorMessage(EMSG_NODEINIT+ecode-1,N_NodeNum,NULL);
  1053.   return(FALSE);
  1054. }
  1055.  
  1056. void FreeNode( void )
  1057. {
  1058.   SendStatus(STAT_CLOSING);
  1059.   if (N_ND->NodeTimer) CleanupTimer(N_ND->NodeTimer);
  1060.   FreeStrList(N_ND->Last_Callers);
  1061.   FreeStrList(N_ND->Last_Uploads);
  1062.   FreeStrList(N_ND->Last_Downloads);
  1063.   FreeStrList(N_ND->Last_Pagers);
  1064.   FreeStrList(N_ND->Last_PWFails);
  1065.   FreeStrList(N_ND->Last_Carrier);
  1066.   FreeStrList(N_ND->OLMList);
  1067.   N_ND->OLMList=NULL; //must be done!!
  1068.  
  1069.   FreeStrList(N_ND->User.ConfAcs.See);
  1070.   FreeStrList(N_ND->User.ConfAcs.Access);
  1071.   FreeStr(N_ND->User.ConfAcs.Name);
  1072.  
  1073.   if (N_ND->BBSCols)
  1074.   {
  1075.     FreeVec(N_ND->BBSCols->MenuTextANSI);
  1076.     FreeVec(N_ND->BBSCols->MenuOpenBracket);
  1077.     FreeVec(N_ND->BBSCols->MenuCloseBracket);
  1078.     FreeVec(N_ND->BBSCols->MenuHighlightANSI);
  1079.     FreeVec(N_ND->BBSCols->MenuDefaultOptANSI);
  1080.     FreeVec(N_ND->BBSCols->MenuPromptANSI);
  1081.     FreeVec(N_ND->BBSCols);
  1082.   }
  1083.   FreeDeviceData(&N_ND->NodeDevice);
  1084.   FreeNodeSettingsData(&N_ND->NodeSettings);
  1085.   SendStatus(STAT_CLOSED);
  1086.   // must be done last cos status won't work otherwise..
  1087.   CloseNodePorts();
  1088.   HBBS_ResetNodeData(N_ND);
  1089. }
  1090.  
  1091. /*
  1092. void HandleAsk(struct AskMsg *AMsg)
  1093. {
  1094.   switch(AMsg->Flags)
  1095.   {
  1096.     case ASK_STATUS:
  1097.       AMsg->Value=N_ND->Status;
  1098.       break;
  1099.   }
  1100.   ReplyMsg((struct Message *)AMsg);
  1101. }
  1102. */
  1103.  
  1104. // returns 1 if quit..
  1105. void HandleStatus(struct StatusMsg *SMsg)
  1106. {
  1107.   switch(SMsg->Status)
  1108.   {
  1109.     case STAT_REQUESTCLOSE:
  1110.       // node must NOT be doing anything if we want to shut it down
  1111.       if (N_ND->Status==STAT_READY) N_ND->RequestShutdown=TRUE;
  1112.       break;
  1113.  
  1114.     case STAT_OPENWINDOW:
  1115.       if (N_ND->NodeSettings.Iconified==TRUE)
  1116.       {
  1117.         OpenNodeWin(scr);
  1118.       }
  1119.       break;
  1120.     case STAT_CLOSEWINDOW:
  1121.       // *C* change to abort con if window closed pressed as we can't actually
  1122.       // care about the console coming in if we're closing the window!
  1123.       // ah, but what if a door does care ??? Umm.. fuck it.. who cares it's staying
  1124.       if (N_ND->NodeSettings.Iconified==FALSE && N_ND->ConWaiting==FALSE)
  1125.       {
  1126.         CloseNodeWin();
  1127.       }
  1128.       break;
  1129.     case STAT_OPENSCREEN:
  1130.       WatchScreenToFront();
  1131.       break;
  1132.     case STAT_CLOSESCREEN:
  1133.       if (N_ND->ConOK==TRUE)
  1134.       {
  1135.         CleanupNodeConsoleWin();
  1136.       }
  1137.       break;
  1138.   }
  1139.  
  1140.   // a status message MAY be sent to the node without the control or other program wanting to be told
  1141.   // that the NODE has recived the message, all messages sent that DONT want a reply WILL be freed..
  1142.  
  1143.   if (SMsg->message.mn_ReplyPort)
  1144.   {
  1145.     ReplyMsg((struct Message *)SMsg);
  1146.   }
  1147.   else
  1148.   {
  1149.     FreeVec(SMsg);
  1150.   }
  1151. }
  1152.  
  1153. void HandleDoorActivityMsg(struct DoorActivityMsg *DMsg) // *C* whatr's this used for now ??
  1154. {
  1155.   switch(DMsg->Status)
  1156.   {
  1157.     case DMSG_DOORSTARTED:
  1158. //      printf("Door Started! (%s)\n",N_ND->ActiveDoor->node.ln_Name);
  1159.       break;
  1160.     case DMSG_DOORFINISHED:
  1161. //      printf("Door Finished!\n");
  1162.       break;
  1163.   }
  1164.   // a door message MAY be sent to the node without the control or other program wanting to be told
  1165.   // that the NODE has recived the message, all messages sent that DONT want a reply WILL be freed..
  1166.  
  1167.   if (DMsg->message.mn_ReplyPort)
  1168.   {
  1169.     ReplyMsg((struct Message *)DMsg);
  1170.   }
  1171.   else
  1172.   {
  1173.     FreeVec(DMsg);
  1174.   }
  1175. }
  1176.  
  1177. void HandleCheckMsg(struct NodeMsg *NMsg)  // *R* needed ?
  1178. {
  1179.   if (NMsg->message.mn_ReplyPort)
  1180.   {
  1181.     ReplyMsg((struct Message *)NMsg);
  1182.   }
  1183.   else
  1184.   {
  1185.     FreeVec(NMsg);
  1186.   }
  1187. }
  1188.  
  1189. void HandleMsg( void )
  1190. {
  1191.   struct NodeMsg *NMsg;
  1192.  
  1193.  
  1194.   while (NMsg=(struct NodeMsg*)GetMsg(N_ND->NodePort))
  1195.   {
  1196.     if ( (NMsg->MsgType==mtype_DOORIO) && ( ((struct DoorIOMsg *)NMsg)->Status==DOORIO_WRITESTR ) )
  1197.     {
  1198.       if (((struct DoorIOMsg *)NMsg)->Data)
  1199.       {
  1200.         if (N_ND->ConOK)
  1201.         {
  1202.           N_ND->ConWrite->io_Command  = CMD_WRITE;
  1203.           N_ND->ConWrite->io_Data     = ((struct DoorIOMsg *)NMsg)->Data;
  1204.           N_ND->ConWrite->io_Length   = -1;
  1205.           DoIO((struct IORequest *)N_ND->ConWrite);
  1206.         }
  1207.         if ((N_ND->LoginType==LOGIN_REMOTE) && (!(N_ND->NodeFlags & NFLG_BLOCKSERIAL)))
  1208.         {
  1209.           AbortSerRead();
  1210.           N_ND->SerWrite->IOSer.io_Command  = CMD_WRITE;
  1211.           N_ND->SerWrite->IOSer.io_Data     = ((struct DoorIOMsg *)NMsg)->Data;
  1212.           N_ND->SerWrite->IOSer.io_Length   = -1;
  1213.           DoIO((struct IORequest *)N_ND->SerWrite);
  1214.         }
  1215.       }
  1216.       ReplyMsg((struct Message *)NMsg);
  1217.     }
  1218.     else
  1219.     {
  1220.       switch(NMsg->MsgType)
  1221.       {
  1222. //        case mtype_ASK:
  1223. //          HandleAsk((struct AskMsg *)NMsg);
  1224. //          break;
  1225.         case mtype_STATUS:
  1226.           HandleStatus((struct StatusMsg *)NMsg);
  1227.           break;
  1228.         case mtype_DOORACTIVITY:
  1229.           HandleDoorActivityMsg((struct DoorActivityMsg *)NMsg);
  1230.           break;
  1231.         case mtype_DOORIO:
  1232.           HandleDoorIOMsg((struct DoorIOMsg *)NMsg);
  1233.           break;
  1234.         case mtype_CHECK:   // all we want to do is get the node to check some stuff
  1235.           HandleCheckMsg(NMsg); // depending on what it's doing...
  1236.           break;
  1237.       }
  1238.     }
  1239.     // we might get a message that does not want a reply.. (like a request shutdown message..)
  1240.   }
  1241. }
  1242.  
  1243. // copied and modified from NodeGUI.c as the version in there does NOT free the fonts!!!!
  1244.  
  1245. int OpenTheDiskFonts( void )
  1246. {
  1247.   int OKSoFar = 1; // reveresed numbers
  1248.   if ((HBBSFont = OpenDiskFont( &HBBS8066 ))==NULL )
  1249.   OKSoFar = 0;
  1250. return ( OKSoFar );
  1251. }
  1252.  
  1253. void NodeMain(void)
  1254. {
  1255.   char outstr[40];
  1256.  
  1257.   if (OpenLibs()==0)
  1258.   {
  1259.     sprintf(outstr,"Starting Node %d",N_ND->NodeNum);
  1260.     HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_DONTCARE);
  1261.  
  1262.     if (OpenTheDiskFonts())
  1263.     {
  1264.       if (scr=LockPubScreen(BBSGlobal->ScreenInfo.PubScreenName))
  1265.       {
  1266.         if (InitNode())
  1267.         {
  1268.           SendStatus(STAT_READY);
  1269.           HBBS_LoadCallsData();
  1270.           LoadWindowSettings();
  1271.           if (N_ND->NodeSettings.Iconified==FALSE) OpenNodeWin(scr);
  1272.           if (N_ND->NodeSettings.StartScreen) OpenNodeConsoleWin();
  1273.  
  1274.           sprintf(outstr,"Node %d Started OK",N_ND->NodeNum);
  1275.           HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_DONTCARE);
  1276.  
  1277.           AwaitConnect();
  1278.  
  1279.           if (N_ND->NodeSettings.Iconified==FALSE) CloseNodeWin();
  1280.           if (N_ND->SettingsOpen) CloseSettingsWinWindow();
  1281.           if (N_ND->InformationOpen) CloseInfoWinWindow();
  1282.           if (N_ND->ConOK) CleanupNodeConsoleWin();
  1283.           if (N_ND->SerOK) CleanupSerial();
  1284.         }
  1285.         FreeNode();
  1286.         UnlockPubScreen(NULL, scr);
  1287.       } else HBBS_DoErrorMessage(EMSG_NOSCREEN,0,NULL);
  1288.       sprintf(outstr,"Node %d Stopped",N_ND->NodeNum);
  1289.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_DONTCARE);
  1290.       CloseFont( HBBSFont ) ;
  1291.     }
  1292.     else  HBBS_DoErrorMessage(EMSG_NOFONT,0,NULL);
  1293.     CloseLibs();
  1294.   } else HBBS_DoErrorMessage(EMSG_NOLIBS,0,NULL);
  1295. }
  1296.  
  1297. int main(int argc,char *argv[])
  1298. {
  1299.   struct MsgPort *tmpport;
  1300.   char tmpstr[20];
  1301.  
  1302.   gargc=argc;
  1303.   gargv=argv;
  1304.  
  1305.   if ((argc<2) || (sscanf(argv[1],"%d",&N_NodeNum)==0))
  1306.   {
  1307.     printf("Invalid/No Paramaters for node!\n");
  1308.     exit (20);
  1309.   }
  1310.   sprintf(tmpstr,"HBBS_Node %d",N_NodeNum);
  1311.   SetProgramName(tmpstr);
  1312.   init();
  1313.   if (BBSGlobal=HBBS_GimmeBBS())
  1314.   {
  1315.     rttags[7]=(ULONG)BBSGlobal->ScreenInfo.PubScreenName;
  1316.     if (N_NodeNum >= BBSGlobal->BBSNodes)
  1317.     {
  1318.       HBBS_DoErrorMessage(EMSG_NODEINVALID,N_NodeNum,NULL);
  1319.     }
  1320.     else
  1321.     {
  1322.       if (N_ND=HBBS_NodeDataPtr(N_NodeNum)) // this should not fail in normal circumstances..
  1323.       {
  1324.         Forbid();
  1325.         tmpport=FindPort(N_ND->PortName);
  1326.         Permit();
  1327.         if (tmpport)
  1328.         {
  1329.           HBBS_DoErrorMessage(EMSG_NODEALREADYUP,N_NodeNum,NULL);
  1330.         }
  1331.         else
  1332.         {
  1333.           // actually already set by control..
  1334.           //N_ND->NodeNum=N_NodeNum; // set the node number (as gained from command line params)
  1335.           NodeMain();
  1336.         }
  1337.       }
  1338.     }
  1339.   } else HBBS_DoErrorMessage(EMSG_NOCTRL,0,NULL);
  1340.   cleanup(0);
  1341. }
  1342.